package com.cskaoyan.user.service.impl;

import com.cskaoyan.mall.commons.exception.ValidateException;
import com.cskaoyan.user.constants.UserRetCode;
import com.cskaoyan.user.dal.entitys.Member;
import com.cskaoyan.user.dal.entitys.UserVerify;
import com.cskaoyan.user.dal.persistence.MemberMapper;
import com.cskaoyan.user.dal.persistence.UserVerifyMapper;
import com.cskaoyan.user.form.UserRegisterRequest;
import com.cskaoyan.user.form.UserVerifyRequest;
import com.cskaoyan.user.service.IUserRegisterService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import tk.mybatis.mapper.entity.Example;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Description：
 * @Author： 黄武
 * @Date： 2022/12/3 15:14
 */
@Slf4j
@Service
public class UserRegisterServiceImpl implements IUserRegisterService {
    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private UserVerifyMapper userVerifyMapper;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String emailFrom;
    @Value("${email.text}")
    private String verifyUrl;
    /**
     * 用户注册
     * @param request
     */
    @Override
    public void register(UserRegisterRequest request) {
        // request判空验证
        if (request == null || "".equals(request)){
            throw new ValidateException(UserRetCode.REQUEST_DATA_NOT_EXIST.getCode(),
                    UserRetCode.REQUEST_DATA_NOT_EXIST.getMessage());
        }
        // 用户名、密码、邮箱判空验证
        if (StringUtils.isEmpty(request.getUserName()) || StringUtils.isEmpty(request.getUserPwd())
        || StringUtils.isEmpty(request.getEmail())){
            throw new ValidateException(UserRetCode.REQUISITE_PARAMETER_NOT_EXIST.getCode(),
                    UserRetCode.REQUISITE_PARAMETER_NOT_EXIST.getMessage());
        }
        // 验证邮箱是否重复
        volidEmail(request.getEmail());
        // 验证用户名是否重复
        volidUsernameRepeat(request.getUserName());

        // 向用户表中插入一条数据
        Member member = new Member();
        member.setUsername(request.getUserName());
        // 密码需要加密处理
        String password = DigestUtils.md5DigestAsHex(request.getUserPwd().getBytes());
        member.setPassword(password);
        member.setEmail(request.getEmail());
        member.setCreated(new Date());
        member.setUpdated(new Date());
        member.setIsVerified("N");
        member.setState(1);
        int i = memberMapper.insert(member);
        if (i != 1){
            throw new ValidateException(UserRetCode.USER_REGISTER_FAILED.getCode(),
                    UserRetCode.USER_REGISTER_FAILED.getMessage());
        }
        // 向用户验证表中加入一条数据
        UserVerify userVerify = new UserVerify();
        userVerify.setUsername(member.getUsername());
        // TODO uuid实际上应该需要更复杂一点，但是这里为了方便一点就设置的简单一点
        String uuid = UUID.randomUUID().toString();
        userVerify.setUuid(uuid);
        userVerify.setRegisterDate(new Date());
        userVerify.setIsVerify("N");
        userVerify.setIsExpire("N");
        int j = userVerifyMapper.insert(userVerify);
        if (j != 1){
            throw new ValidateException(UserRetCode.USER_REGISTER_FAILED.getCode(),
                    UserRetCode.USER_REGISTER_FAILED.getMessage());
        }
        // 给用户发送验证激活邮件，实现多线程方式发送
        new Thread(new Runnable() {
            @Override
            public void run() {
                sendMsg(request,uuid);
            }
        }).start();
    }


    /**
     * 验证邮箱是否已存在
     * @param email
     */
    private void volidEmail(String email) {
        Example example = new Example(Member.class);
        example.createCriteria().andEqualTo("email",email);
        List<Member> members = memberMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(members)){
            throw new ValidateException(UserRetCode.EMAIL_ALREADY_EXISTS.getCode(),
                    UserRetCode.EMAIL_ALREADY_EXISTS.getMessage());
        }
    }


    /**
     * 给注册用户发送激活邮件
     * @param request
     */
    private void sendMsg(UserRegisterRequest request,String uuid) {
        SimpleMailMessage message = new SimpleMailMessage();
        String subject = "用户认证激活邮件";
        // 转到激活认证接口
        String url = String.format(verifyUrl,request.getUserName(),uuid);
        // 直接从配置文件读取
        message.setSubject(subject);
        message.setText(url);
        message.setTo(request.getEmail());
        message.setFrom(emailFrom);
        mailSender.send(message);
    }


    /**
     *  验证用户名是否已存在
     * @param username
     */
    private void volidUsernameRepeat(String username) {
        Example example = new Example(Member.class);
        example.createCriteria().andEqualTo("username",username);
        List<Member> members = memberMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(members))
            throw new ValidateException(UserRetCode.USERNAME_ALREADY_EXISTS.getCode(),
                    UserRetCode.USERNAME_ALREADY_EXISTS.getMessage());
    }


    /**
     * 用户激活
     * @param request
     */
    @Override
    public void verify(UserVerifyRequest request) {
        // 更新用户激活表中的用户状态，先看是否超市
        Example example = new Example(UserVerify.class);
        example.createCriteria().andEqualTo("username",request.getUsername())
                .andEqualTo("uuid",request.getUuid());
        List<UserVerify> userVerifies = userVerifyMapper.selectByExample(example);
        // 看是否存在这条数据
        if (CollectionUtils.isEmpty(userVerifies)){
            throw new ValidateException(UserRetCode.USERVERIFY_INFOR_INVALID.getCode(),
                    UserRetCode.USERVERIFY_INFOR_INVALID.getMessage());
        }
        // 如果存在，查看验证连接是否过期，限制时间为1天
        long register = userVerifies.get(0).getRegisterDate().getTime();
        long now = new Date().getTime();
        if ((now-register) > 1000 * 60 * 60 * 24 ){
            throw new ValidateException(UserRetCode.USERVERIFY_TIMEOUT.getCode(),
                    UserRetCode.USERVERIFY_TIMEOUT.getMessage());
        }
        // 更新用户激活表
        UserVerify userVerify = userVerifies.get(0);
        userVerify.setIsVerify("Y");
        userVerify.setIsExpire("N");
        int i = userVerifyMapper.updateByExample(userVerify, example);
        if (i != 1){
            throw new ValidateException(UserRetCode.USER_REGISTER_VERIFY_FAILED.getCode(),
                    UserRetCode.USER_REGISTER_VERIFY_FAILED.getMessage());
        }
        // 更新用户表中的用户激活状态
        Example memberExample = new Example(Member.class);
        memberExample.createCriteria().andEqualTo("username",request.getUsername());
        List<Member> members = memberMapper.selectByExample(memberExample);
        // 看是否存在这条数据
        if (CollectionUtils.isEmpty(members)){
            throw new ValidateException(UserRetCode.USERVERIFY_INFOR_INVALID.getCode(),
                    UserRetCode.USERVERIFY_INFOR_INVALID.getMessage());
        }
        // 更新用户表
        Member member = members.get(0);
        member.setIsVerified("Y");
        member.setUpdated(new Date());
        int j = memberMapper.updateByPrimaryKey(member);
        if (j != 1){
            throw new ValidateException(UserRetCode.USER_REGISTER_VERIFY_FAILED.getCode(),
                    UserRetCode.USER_REGISTER_VERIFY_FAILED.getMessage());
        }
    }
}
